package com.xinkao.example.config.aspect;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xinkao.example.config.annotation.SysLog;
import com.xinkao.example.domain.entity.LogEntity;
import com.xinkao.example.service.LogService;
import com.xinkao.example.util.HttpContextUtils;
import com.xinkao.example.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;


/**
 * 系统日志，切面处理类
 *
 * @author Mark sunlightcs@gmail.com
 */
@Slf4j
@Aspect
@Component
public class SysLogAspect {
	@Resource
	private LogService logService;
	@Resource
	private RedisUtils redisUtils;


	@Pointcut("@annotation(com.xinkao.example.config.annotation.SysLog)")
	public void pointCut() {
	}

	@Around("pointCut()")
	private Object saveSysLog(ProceedingJoinPoint joinPoint) throws Throwable {
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		LogEntity logEntity = new LogEntity();
		SysLog syslog = method.getAnnotation(SysLog.class);
		if(syslog != null){
			//注解上的描述
			String module = syslog.module();
			String operate = syslog.operate();
			logEntity.setOperateModule(module);
			logEntity.setOperate(operate);
			// 根据描述处理记录内容
			if(HttpContextUtils.getMethod().equals(HttpContextUtils.POST)){
				Object[] args = joinPoint.getArgs();
				Object[] arguments = new Object[args.length];
				for (int i = 0; i < args.length; i++) {
					if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse || args[i] instanceof MultipartFile) {
						continue;
					}
					arguments[i] = args[i];
				}
				logEntity.setParam(JSON.toJSONString(arguments)
						.replaceAll("\\[", "")
						.replaceAll("]", ""));
			}else if(HttpContextUtils.getMethod().equals(HttpContextUtils.GET)){
				logEntity.setParam(JSON.toJSONString(HttpContextUtils.getParameterMap())
						.replaceAll("\\[", "")
						.replaceAll("]", ""));
			}
		}
		logEntity.setIpAddress(HttpContextUtils.getIpAddr());
		logEntity.setOperatePlatform(HttpContextUtils.getBrowser() + "," + HttpContextUtils.getPlatform());
		long begin = System.nanoTime();
		Object obj = joinPoint.proceed();
		long end = System.nanoTime();
		//操作人信息
		if(ObjectUtil.isNotEmpty(SecurityUtils.getSubject().getPrincipal())) {
			JSONObject user = redisUtils.get(SecurityUtils.getSubject().getPrincipal().toString(), JSONObject.class);
			logEntity.setOperator(user.getString("userName"));
			logEntity.setRoleName(user.getString("roleName"));
			logEntity.setCreateBy(user.getString("userId"));
		}
		logEntity.setOperatingTime(new Date());
		if(ObjectUtil.isNotEmpty(obj)){
			logEntity.setResult(obj.toString());
		}
		logEntity.setMethod(joinPoint.getSignature().toString());
		logEntity.setUseTime((end - begin) / 1000000);
		logService.save(logEntity);
		log.debug("\n请求方法：{}\n请求参数：{}\n返回结果：{}\n执行时间：{} ms",
				logEntity.getMethod(), logEntity.getParam(), logEntity.getResult(), logEntity.getUseTime());
		return obj;

	}


}
